<template>
  <el-dialog
    :title="title"
    :modelValue="visible"
    @update:modelValue="emit('update:visible', $event)"
    width="900px"
    append-to-body
    class="seal-dialog"
  >
    <template #default>
      <div style="padding-right: 24px;">
        <el-form ref="sealFormRef" :model="form" :rules="rules" label-width="140px" label-position="left" style="padding: 20px 0 20px 24px">
          <el-row :gutter="20">
            <el-col :span="24">
              <el-form-item label="编号" prop="number">
                <el-input v-model="form.number" placeholder="请输入编号" :readonly="true" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="申请人" prop="presidentsName">
                <el-input v-model="form.presidentsName" placeholder="请输入编号" disabled />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="申请部门" prop="deptId">
                <el-tree-select
                  v-model="form.deptId"
                  :data="deptTree"
                  placeholder="请选择申请部门"
                  :props="{ label: 'label', value: 'id', children: 'children' }"
                  check-strictly
                  filterable
                  :default-expand-all="true"
                  style="width: 100%"
                  @visible-change="handleVisibleChange"
                />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="项目名称" prop="proId">
                <el-select
                  v-model="form.proId"
                  placeholder="请输入项目名称搜索"
                  clearable
                  filterable
                  remote
                  reserve-keyword
                  :remote-method="searchProjects"
                  :loading="projectLoading"
                  style="width: 100%"
                  @change="handleProjectChange"
                  @visible-change="handleProjectVisibleChange"
                >
                  <el-option
                    v-for="project in projectList"
                    :key="project.id"
                    :label="`${project.proName} (${project.proNumber})`"
                    :value="project.id"
                  />
                  <template #empty>
                    <div class="text-center p-2">
                      <span v-if="projectSearchKeyword && projectList.length === 0"> 未找到相关项目 </span>
                      <span v-else> 请输入项目名称进行搜索 </span>
                    </div>
                  </template>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="印章类型" prop="sealType">
                <el-select
                  v-model="sealTypeArray"
                  placeholder="请选择印章类型"
                  multiple
                  filterable
                  allow-create
                  style="width: 100%;"
                  @change="onSelectChange"
                >
                  <el-option
                    v-for="item in sealTypeOptions"
                    :key="item"
                    :label="item"
                    :value="item"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="用章事由" prop="sealCause">
                <el-input v-model="form.sealCause" placeholder="请输入用章事由" type="textarea" :rows="4" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="印章文件" prop="sealFiles" style="width: 100%">
                <div style="display: flex; gap: 8px; width: 100%">
                  <el-input v-model="sealFileInput.fileName" placeholder="请输入文件名"/>
                  <el-input-number v-model="sealFileInput.fileCount" :min="1" placeholder="份数"/>
                  <el-button type="primary" @click="addSealFile" :disabled="!sealFileInput.fileName || !sealFileInput.fileCount">确定</el-button>
                </div>
              </el-form-item>
              <el-form-item v-if="sealFiles.length > 0">
                <el-tag
                  v-for="(file, idx) in sealFiles"
                  :key="file.fileName + idx"
                  closable
                  @close="removeSealFile(idx)"
                  style="margin-right: 8px; margin-bottom: 4px"
                >
                  {{ file.fileName }}（{{ file.fileCount }}份）
                </el-tag>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="使用日期" prop="useDate">
                <el-date-picker clearable v-model="form.useDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择使用日期" style="width: 100%"> </el-date-picker>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="使用类型" prop="useType">
                <el-select v-model="form.useType"  :empty-values="[null, undefined]" placeholder="请选择使用类型" style="width: 100%">
                  <el-option
                    v-for="item in seal_use_type"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <!-- 其它输入框 + 按钮 -->
              <el-form-item
                v-if="openOtherInput"
                label="其它印章"
                style="display: flex; align-items: center; width: 100%;"
              >
                <el-input
                  v-model="otherSealType"
                  placeholder="请输入其它印章类型"
                  clearable
                  style="flex: 1; margin-right: 8px;"
                  @keyup.enter="addOtherSealType"
                />
                <el-button type="primary" @click="addOtherSealType" style="width: 100px;">
                  确定
                </el-button>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="备注" prop="remark">
                <el-input v-model="form.remark" placeholder="请输入备注" type="textarea" :rows="3" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
    </template>
    <template #footer>
      <div class="dialog-footer">
        <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, toRefs, computed, onMounted, watch } from 'vue';
import { getCurrentInstance } from 'vue';
import type { ComponentInternalInstance } from 'vue';
import { addSeal, updateSeal, getSealNumber, getSeal, getDeptTree } from '@/api/general/administration/seal';
import type { SealForm, SealFile, DeptTreeNode } from '@/api/general/administration/seal/types';
import { getSuperior } from '@/api/system/user';
import type { UserVO } from '@/api/system/user/types';
import { pageListForQuery, getProInfo } from '@/api/project/init/proInfo';
import { useUserStore } from '@/store/modules/user';
import type { FormInstance, FormRules } from 'element-plus';
import type { ProInfoVO } from '@/api/project/init/proInfo/types';

const props = defineProps({
  title: {
    type: String,
    default: ''
  },
  visible: {
    type: Boolean,
    default: false
  }
});

// 项目执行总裁选择相关
const showPresidentSelector = ref(false);
const selectedPresidents = ref([]);

const emit = defineEmits(['update:visible', 'success']);

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { seal_status, seal_use_type } = toRefs<any>(proxy?.useDict('seal_status', 'seal_use_type'));

const buttonLoading = ref(false);
const sealFormRef = ref<FormInstance>();
const postCategories = ref<string[]>([]);

// 印章类型初始化
const sealTypeOptions = ['公章', '财务章', '法人章', '测绘资质章', '其它'] as const;
const otherSealType = ref('');
// 新增本地变量 sealTypeArray
const sealTypeArray = ref<string[]>([]);
// 内部用于 select 显示的数组（包含“其它”触发输入框）
const internalSelect = ref<string[]>([]);
// 判断是否显示“其它”输入框
const openOtherInput = ref(false);

// 用户信息
const userStore = useUserStore();

const projectList = ref<ProInfoVO[]>([]);

// 搜索关键词
const projectSearchKeyword = ref('');
const flowSearchKeyword = ref('');
const projectLoading = ref(false);
const flowLoading = ref(false);

// 防抖计时器
let projectSearchTimer: NodeJS.Timeout | null = null;

// 判断是否为新增
const isAdd = computed(() => !form.value.id);

const initFormData: SealForm = {
  id: undefined,
  number: undefined,
  deptId: undefined,
  proId: undefined,
  useDate: undefined,
  useType: undefined,
  sealType: undefined,
  sealCause: undefined,
  status: '0', // 默认未审批
  approverIdea: undefined,
  sealFiles: [],
  presidentsName: userStore.name
};

const form = ref<SealForm>({ ...initFormData });
const rules = reactive<FormRules>({
  number: [{ required: true, message: '请输入编号', trigger: 'blur' }],
  presidentsName: [{ required: true, message: '请输入申请人名称', trigger: 'blur' }],
  deptId: [{ required: true, message: '请选择申请部门', trigger: 'change' }],
  proId: [{ required: true, message: '请选择项目', trigger: 'change' }],
  sealFiles: [
    {
      validator: (rule, value, callback) => {
        if (!sealFiles.value.length) {
          callback(new Error('请至少添加一个印章文件'));
        } else {
          callback();
        }
      },
      trigger: 'change',
      required: true,
      message: '请至少添加一个印章文件'
    }
  ],
  useDate: [{ required: true, message: '请选择使用日期', trigger: 'change' }],
  useType: [{ required: true, message: '请选择使用类型', trigger: 'change' }],
  sealType: [
    {
      validator: (rule, value, callback) => {
        if (!sealTypeArray.value.length) {
          callback(new Error('请选择印章类型'));
        } else {
          callback();
        }
      },
      trigger: 'change',
      required: true,
      message: '请选择印章类型'
    }
  ],
  sealCause: [{ required: true, message: '请输入用章事由', trigger: 'blur' }]
});

// 部门树初始化
const deptTree = ref<DeptTreeNode[]>([]);
const deptTreeSelectRef = ref();

// 获取部门树
const fetchDeptTree = async () => {
  try {
    const res = await getDeptTree();
    const processNode = (node: any) => {
      if (node.children && node.children.length > 0) {
        // 有子节点 → 禁用，但允许展开
        node.disabled = true;
        node.children.forEach(processNode); // 递归处理子节点
      } else {
        // 叶子节点 → 可选
        node.disabled = false;
      }
    };
    if (Array.isArray(res.data)) {
      res.data.forEach(processNode);
    }
    deptTree.value = res.data;
  } catch (error) {
    console.error('获取部门树失败:', error);
    proxy?.$modal.msgError('获取部门树失败');
  }
};


// 下拉框打开时展开全部节点
const handleVisibleChange = (visible: boolean) => {
  console.log('handleVisibleChange', visible);
  if (visible) {
    // 展开全部节点（treeSelect 内部的 tree 是 el-tree 实例）
    setTimeout(() => {
      const tree = deptTreeSelectRef.value?.$refs?.tree;
       tree?.expandAll?.();
    }, 0);
  }
};

// 绑定印章类型下拉框处理'其它'选择的逻辑
const onSelectChange = (val: string[]) => {
  // 如果选了“其它”，打开输入框
  openOtherInput.value = val.includes('其它');
  // 保留 “其它” 用于触发 UI
  if (!val.includes('其它')) val.push('其它');
  // 更新最终提交数据，不包含 “其它”
  sealTypeArray.value = val.filter(item => item !== '其它');
};

// 点击按钮添加自定义印章
const addOtherSealType = () => {
  const value = otherSealType.value.trim();
  if (value && !sealTypeArray.value.includes(value)) {
    // 添加到最终数据
    sealTypeArray.value.push(value);
    // 自动加入 select 显示
    if (!internalSelect.value.includes(value)) {
      internalSelect.value.push(value);
    }
    // 清空输入框
    otherSealType.value = '';
  }
  // 点击确定后关闭输入框
  openOtherInput.value = false;
  // 保持 select 中有“其它”
  if (!internalSelect.value.includes('其它')) {
    internalSelect.value.push('其它');
  }
};


const superiorOptions = ref<UserVO[]>([]);

// 获取上级用户列表
const fetchSuperiorList = async () => {
  try {
    const res = await getSuperior();
    superiorOptions.value = res.data;
  } catch (error) {
    console.error('获取上级用户列表失败:', error);
    proxy?.$modal.msgError('获取上级用户列表失败');
  }
};

// 通过项目id获取项目信息回显
const getProjectInfo = async (projectId: string | number) => {
  try {
    const res = await getProInfo(projectId);
    if (res.data) {
      // 清空并只保留当前项目（适合只需要一个选项的情况）
      projectList.value = [{
        id: res.data.id,
        contractId: res.data.contractId,
        proName: res.data.proName,
        proNumber: res.data.proNumber,
        proType: res.data.proType,
        proContent: res.data.proContent,
        proPresidentsId: res.data.proPresidentsId,
        proPresidentsName: res.data.proPresidentsName,
        proLeadersId: res.data.proLeadersId,
        proAmount: res.data.proAmount,
        proAmountRemark: res.data.proAmountRemark,
        remark: res.data.remark,
        proStatus: res.data.proStatus,
      }];
    }
  } catch (error) {
    console.error('通过项目id获取项目信息回显失败:', error);
    proxy?.$modal.msgError('通过项目id获取项目信息回显失败');
  }
};


/** 远程搜索项目 */
const searchProjects = (query: string) => {
  projectSearchKeyword.value = query;

  if (projectSearchTimer) {
    clearTimeout(projectSearchTimer);
  }

  projectSearchTimer = setTimeout(() => {
    // 如果查询为空，加载所有项目；否则按名称搜索
    getProjectList(query || '');
  }, 300); // 300ms防抖
};

/** 获取项目列表 */
const getProjectList = async (searchKeyword = '') => {
  try {
    projectLoading.value = true;
    const res = await pageListForQuery({
      pageNum: 1,
      pageSize: 50, // 减少单次加载数量
      flowStatus: '3',
      proName: searchKeyword || undefined // 支持名称搜索
    });
    projectList.value = res.rows || [];
  } catch (error) {
    console.error('获取项目列表失败:', error);
    ElMessage.error('获取项目列表失败');
  } finally {
    projectLoading.value = false;
  }
};

/** 处理项目选择变化 */
const handleProjectChange = (value: number | string | undefined) => {
  flowSearchKeyword.value = ''; // 清空流程搜索关键词

  // 项目改变时不清空工作日志列表，允许多个项目的数据共存
};

/** 处理项目下拉框显示状态变化 */
const handleProjectVisibleChange = (visible: boolean) => {
  if (visible) {
    // 下拉框打开时，如果没有数据则加载默认数据
    if (projectList.value.length === 0) {
      // 触发远程搜索方法，传入空字符串来加载所有项目
      searchProjects('');
    }
  }
};

onMounted(() => {
  fetchDeptTree();
  fetchSuperiorList();
});

/** 获取编号 */
const getNumber = async () => {
  try {
    const res = await getSealNumber();
    if (res.data) {
      form.value.number = res.data;
      // 强制更新表单数据
      sealFormRef.value?.validateField('number');
    }
  } catch (error) {
    console.error('获取编号失败:', error);
    proxy?.$modal.msgError('获取编号失败');
  }
};

/** 取消按钮 */
const cancel = () => {
  reset();
  emit('update:visible', false);
};

/** 表单重置 */
const reset = async () => {
  Object.assign(form.value, initFormData);
  sealFormRef.value?.resetFields();
  sealTypeArray.value = [];
  principalIdsArray.value = [];
  sealFiles.value = [];
  form.value.useDate = undefined;
  form.value.useType = undefined;
  form.value.sealCause = undefined;
  form.value.deptId = undefined;
  // 如果是新增，获取编号
  if (!form.value.id) {
    await getNumber();
  }
};

const upload = reactive({
  url: import.meta.env.VITE_APP_BASE_API + '/common/upload',
  headers: { Authorization: 'Bearer ' + useUserStore().token },
  fileList: [] as any[]
});

const sealFileInput = reactive({ fileName: '', fileCount: 1 });
const sealFiles = ref<SealFile[]>([]);

const addSealFile = () => {
  if (sealFileInput.fileName && sealFileInput.fileCount) {
    sealFiles.value.push({ fileName: sealFileInput.fileName, fileCount: sealFileInput.fileCount });
    sealFileInput.fileName = '';
    sealFileInput.fileCount = 1;
  }
};

const removeSealFile = (idx: number) => {
  sealFiles.value.splice(idx, 1);
};


// 添加principalIdsArray响应式变量
const principalIdsArray = ref<(string | number)[]>([]);

/** 提交按钮 */
const submitForm = () => {
  sealFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      buttonLoading.value = true;
      try {
        form.value.sealType = sealTypeArray.value.join(',');
        form.value.principalIds = principalIdsArray.value.join(',');
        const submitData = { ...form.value, sealFiles: sealFiles.value };
        if (form.value.id) {
          await updateSeal(submitData);
        } else {
          await addSeal(submitData);
        }
        proxy?.$modal.msgSuccess('操作成功');
        emit('update:visible', false);
        emit('success');
      } catch (error) {
        console.error('提交失败:', error);
        proxy?.$modal.msgError('操作失败');
      } finally {
        buttonLoading.value = false;
      }
    }
  });
};

const openDialog = async (data?: SealForm) => {
  if (data) {
    Object.assign(form.value, data);
    sealTypeArray.value = data.sealType ? data.sealType.split(',') : [];
    // 等待上级用户列表加载完成
    if (superiorOptions.value.length === 0) {
      await fetchSuperiorList();
    }
    principalIdsArray.value = data.principalIds ? data.principalIds.split(',').map((id) => String(id)) : [];
    sealFiles.value = Array.isArray((data as any).sealFiles)
      ? (data as any).sealFiles.map((f: any) => ({
          fileName: f.fileName,
          fileCount: f.fileCount
        }))
      : [];
  } else {
    await reset();
  }
};

defineExpose({
  form,
  reset,
  openDialog
});



</script>

<style scoped>
.seal-dialog :deep(.el-dialog__header) {
  text-align: center;
}

/* 合同对话框中的用户选择器样式 */
.user-selector-container {
  width: 100%;
}

.user-selector-container .selected-users {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 8px;
  min-height: 20px;
}

/* 对话框样式优化 */
:deep(.el-dialog__body) {
  max-height: 70vh;
  overflow-y: auto;
}


</style>
